<template>
	<!-- Header: Display Name and IP -->
	<div class="info-header">
		<span class="name">{{ longname }}</span>
		<span class="ip">{{ ip }}</span>
		<!-- <el-button @click="change" style="padding: 0 20px">change</el-button> -->
	</div>
	<div style="height: 100%;">
		<div class="container">
			<div class="left-side" id="network-details" style="width: 100%; height: 100%;"></div>
			<div class="right-side">
				<div class="clean">
					<img src="@/assets/images/dataclean.png" />
				</div>
				<div class="graph-modal">
					<div v-if="selectedGraph === 'input'">
						<Input :data="ioData" />
					</div>
					<div v-if="selectedGraph === 'output'">
						<Output :data="ioData" />
					</div>
					<div v-if="selectedGraph === 'cpu'">
						<CPU :data="cpuData" />
					</div>
					<div v-if="selectedGraph === 'gpu'">
						<Gpu :data="gpuData" />
					</div>
					<div v-if="selectedGraph === 'gpurate'">
						<GpuRate :data="gpuRate" />
					</div>
					<div v-if="selectedGraph === 'memory'">
						<Memory :data="memData" />
					</div>
					<div v-if="selectedGraph === 'diskread'">
						<DiskRead :data="diskRead" />
					</div>
					<div v-if="selectedGraph === 'diskwrite'">
						<DiskWrite :data="diskWrite" />
					</div>

				</div>
			</div>
		</div>
	</div>
</template>

<script>
import CPU from "./CPUGraph.vue";
import Memory from "./MemoryGraph.vue";
import Gpu from "./GpuGraph.vue";
import Input from "./InputGraph.vue";
import Output from "./OutputGraph.vue";
import GpuRate from "./GpuRateGraph.vue";
import DiskRead from "./DiskReadGraph.vue";
import DiskWrite from "./DiskWriteGraph.vue";
import axios from 'axios';
import * as echarts from 'echarts';

export default {
	components: {
		CPU,
		Memory,
		Gpu,
		Input,
		Output,
		GpuRate,
		DiskRead,
		DiskWrite
	},
	props: {
		name: {
			type: String,
			default: "",
		}
	},
	data() {
		return {
			data: [],
			cpuData: [],
			memData: [],
			gpuData: [],
			gpuRate: [],
			diskRead: [],
			diskWrite: [],
			ioData: [],
			jsonData: {},
			filteredInstances: {},
			ip: "",
			longname: "",
			intervalId: null,
			showGraphModal: false,
			selectedGraph: null,
			currentState: 0,
			ws: null,
			message: '',
			option: [
				{
					tooltip: {},
					series: [
						{
							type: 'graph',
							layout: 'none',
							data: [
								{ name: '通', x: 200, y: 100, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [90, 90], label: { fontSize: 30 } },
								{ name: '算', x: 100, y: 200, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [90, 90], label: { fontSize: 30 } },
								{ name: '存', x: 300, y: 200, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [90, 90], label: { fontSize: 30 } },
								{ name: 'Input', x: 150, y: 0, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [100, 100] },
								{ name: 'Output', x: 250, y: 0, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [100, 100] },
								{ name: 'CPU', x: 0, y: 150, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [100, 100] },
								{ name: 'GPU', x: 0, y: 250, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [100, 100] },
								{ name: 'GPU %', x: 80, y: 310, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [100, 100] },
								{ name: 'Memory', x: 400, y: 150, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [100, 100] },
								{ name: 'Disk Wr', x: 400, y: 250, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [100, 100] },
								{ name: 'Disk Rd', x: 320, y: 310, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [100, 100] },
							],
							links: [
								{ source: '通', target: '算', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
								{ source: '算', target: '存', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
								{ source: '存', target: '通', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
								{ source: '通', target: 'Input', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
								{ source: '通', target: 'Output', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
								{ source: '算', target: 'CPU', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
								{ source: '算', target: 'GPU', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
								{ source: '算', target: 'GPU %', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
								{ source: '存', target: 'Memory', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
								{ source: '存', target: 'Disk Wr', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
								{ source: '存', target: 'Disk Rd', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							], // 初始化为空
							label: {
								show: true,
								position: 'inside',
								formatter: '{b}',
								color: 'black',
								fontSize: 22,
							},
							lineStyle: {
								curveness: 0,
								width: 2,
								color: 'white',
								opacity: 1
							},
						}
					],

				},
			]
		};
	},
	methods: {
		connectWebSocket() {
			// 创建 WebSocket 连接
			this.ws = new WebSocket("ws://10.112.51.79:38414/ws");

			// 监听消息
			this.ws.onmessage = (event) => {
				console.log("Received:", event.data);
				this.message = event.data; // 显示接收到的消息
				if (this.message.includes("U 1")) {
					this.change(1);
				} else if (this.message.includes("H 1 2")) {
					this.change(0);
				}
			};

			// 监听 WebSocket 连接关闭
			this.ws.onclose = () => {
				console.log("WebSocket connection closed");
			};

			// 监听 WebSocket 错误
			this.ws.onerror = (error) => {
				console.error("WebSocket error:", error);
			};
		},
		sendMessage() {
			if (this.ws && this.ws.readyState === WebSocket.OPEN) {
				// 发送消息
				this.ws.send("Hello from Vue!");
			}
		},
		async fetchData() {
			try {
				let that = this;
				await axios.get(`http://10.112.51.79:39898/get_nf_data?nf=${this.name}`)
					.then(function (res) {
						that.data = res.data;
					});
				this.cpuData = this.data.phy_cpu_list;
				this.memData = this.data.phy_mem_list;
				this.gpuData = this.data.gpu_list;
				this.ioData = this.data.net_io_list;
				this.gpuRate = this.data.gpu_rate;
				this.diskRead = this.data.disk_read;
				this.diskWrite = this.data.disk_write;
				this.ip = this.data.ip;
				this.longname = this.data.name;
				// console.log(this.gpuRate);
				if (!this.showGraphModal)
					this.updateChartData();
			} catch (error) {
				console.error('Failed to fetch data:', error);
			}
		},
		async loadData() {
			try {
				// 从 public 目录加载 data.json 文件
				const response = await fetch('/free5gc.json');
				if (response.ok) {
					this.jsonData = await response.json();
					this.filteredInstances = this.jsonData.filter(instance =>
						instance.nfType === this.name.toUpperCase()
					);
				} else {
					throw new Error('无法加载文件');
				}
			} catch (error) {
				console.error(error);
			}
		},
		initChart() {
			const container = document.getElementById('network-details');
			if (container) {
				this.myChart = echarts.init(container);
				this.myChart.setOption(this.option[0]);
			}
			// 添加点击事件
			this.myChart.on('click', this.handleNodeClick);
		},
		destroyChart() {
			if (this.myChart) {
				this.myChart.dispose(); // 销毁图表实例
			}
		},
		handleNodeClick(params) {
			// this.selectedGraph = params.name.toLowerCase(); // 更新点击的节点名称
			const componentMap = {
				CPU: 'CPU',
				Memory: 'Memory',
				GPU: 'Gpu',
				Input: 'Input',
				Output: 'Output',
				'GPU %': 'GpuRate',
				'Disk Wr': 'DiskWrite',
				'Disk Rd': 'DiskRead',
			};
			this.selectedGraph = componentMap[params.name].toLowerCase();
			if (this.selectedGraph) {
				// this.selectedGraph = componentName;
				this.showGraphModal = true;
			}
		},
		updateChartData() {
			this.myChart.setOption({
				series: [
					{
						type: 'graph',
						layout: 'none',
						data: [
							{ name: '通', x: 200, y: 100, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [120, 120], label: { fontSize: 40 } },
							{ name: '算', x: 100, y: 200, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [120, 120], label: { fontSize: 40 } },
							{ name: '存', x: 300, y: 200, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [120, 120], label: { fontSize: 40 } },
							{ name: 'Input', x: 150, y: 0, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [120, 120] },
							{ name: 'Output', x: 250, y: 0, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [120, 120] },
							{ name: 'CPU', x: 0, y: 150, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [120, 120] },
							{ name: 'GPU', x: 0, y: 250, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [120, 120] },
							{ name: 'GPU %', x: 80, y: 310, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [120, 120] },
							{ name: 'Memory', x: 400, y: 150, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [120, 120] },
							{ name: 'Disk Wr', x: 400, y: 250, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [120, 120] },
							{ name: 'Disk Rd', x: 320, y: 310, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [120, 120] },
						].map(item => {
							if (item.name === 'CPU') {
								item.label = { show: true, position: 'inside', formatter: `CPU\n${this.cpuData[this.cpuData.length - 1]}m` };
							} else if (item.name === 'GPU') {
								item.label = { show: true, position: 'inside', formatter: `GPU\n${this.gpuData[this.gpuData.length - 1]}Mi` };
							} else if (item.name === 'Memory') {
								item.label = { show: true, position: 'inside', formatter: `Memory\n${this.memData[this.memData.length - 1]}Mi` };
							} else if (item.name === 'Input') {
								item.label = { show: true, position: 'inside', formatter: `Input\n${this.ioData[this.ioData.length - 1].toFixed(2)}Mb/s` };
							} else if (item.name === 'Output') {
								item.label = { show: true, position: 'inside', formatter: `Output\n${this.ioData[this.ioData.length - 1].toFixed(2)}Mb/s` };
							} else if (item.name == 'GPU %') {
								item.label = { show: true, position: 'inside', formatter: `GPU %\n${this.gpuRate[this.gpuRate.length - 1]}%` };
							} else if (item.name == 'Disk Wr') {
								item.label = { show: true, position: 'inside', formatter: `Disk Wr\n${(this.diskWrite[this.diskWrite.length - 1]/1000).toFixed(2)}kB` };
							} else if (item.name == 'Disk Rd') {
								item.label = { show: true, position: 'inside', formatter: `Disk Rd\n${(this.diskRead[this.diskRead.length - 1]/1000).toFixed(2)}kB` };
							}
							return item;
						}),
						links: [
							{ source: '通', target: '算', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: '存', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: '通', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '通', target: 'Input', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '通', target: 'Output', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: 'CPU', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: 'GPU', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: 'GPU %', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: 'Memory', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: 'Disk Wr', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: 'Disk Rd', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
						],
						label: {
							show: true,
							position: 'inside',
							formatter: '{b}',
							color: 'black',
							fontSize: 22,
						},
						lineStyle: {
							curveness: 0,
							width: 2,
							color: 'white',
							opacity: 1
						},
					}
				],
			});
		},
		showGraph(type) {
			this.selectedGraph = type;
			this.showGraphModal = true;
		},
		closeGraph() {
			this.showGraphModal = false;
			this.selectedGraph = null;
			if (this.myChart) {
				this.myChart.dispose();
			}
			// 重新初始化图表
			this.$nextTick(() => {
				this.initChart();
			});
		},
	},
	mounted() {
		this.connectWebSocket();
		console.log(this.ws);
		this.$nextTick(async () => {
			await this.loadData();
			this.initChart(); // 确保容器已渲染后再初始化
			this.fetchData();
			this.intervalId = setInterval(this.fetchData, 1000);
		});
	},
	beforeUnmount() {
		if (this.intervalId) {
			clearInterval(this.intervalId);
		}
		if (this.myChart) {
			this.myChart.dispose(); // 销毁图表实例
		}
		// 关闭 WebSocket 连接
		if (this.ws) {
			this.ws.close();
		}
	}
};
</script>

<style scoped>
.container {
	display: grid;
	grid-template-columns: 3fr 2fr;
	/* 左侧2份，右侧1份 */
	width: 100%;
	height: 100%;
}

.left-side {
	width: 90%;
	height: 100%;
}

.right-side {
	display: flex;
	flex-direction: column;
	width: 100%;
	height: 100%;
}

.clean {
	flex: 1;
	height: 100%;
	width: 90%;
	padding: 20px;
}

.clean img{
	width: 100%;
	height: 90%;
}

.graph-modal {
	flex: 1;
	height: 100%;
}


.info-header {
	position: absolute;
	z-index: 1;
	display: flex;
	justify-content: center;
	align-items: center;
	padding: 20px 20px;
	background-color: transparent;
	font-size: 24px;
	font-weight: bold;
	border-radius: 10px;
	max-width: 100%;
	text-shadow: 1px 1px 2px #000;
}

.name,
.ip {
	display: inline-block;
	margin: 0 10px;
	font-weight: bolder;
}

.name {
	color: #4CAF50;
}

.ip {
	color: #4CAF50;
}

.info-header .name::before {
	content: 'Name: ';
	font-weight: bold;
}

.info-header .ip::before {
	content: 'IP: ';
	font-weight: bold;
}

.info-header:hover {
	background-color: #444;
	transition: background-color 0.3s;
	cursor: pointer;
}
</style>